# encoding: utf-8
# @File   : point_creator.py
# @Author : 乖孩子
# @Date   : 2025/07/24 16:29:59

import copy
from concurrent.futures import ThreadPoolExecutor
from utils.http_client import HttpClient
from utils.file_handler import read_authorization


class PointCreator:
    def __init__(self, logger):
        self.logger = logger
        self.http_client = HttpClient(logger, max_retries=2)
        self.running = False

    def create_points(self, start, total, server_ip, progress_callback, status_callback):
        """批量创建测点"""
        self.running = True
        success_count = 0
        error_count = 0

        # 读取认证信息
        authorization = read_authorization()
        if not authorization:
            self.logger.error("未找到认证信息，请先登录")
            status_callback(False, "未找到认证信息，请先登录")
            return

        self.logger.info(f"开始批量创建测点 - 起始编号: {start}, 总数: {total}, 服务器: {server_ip}")

        # 生成数据源列表
        data_sources = [f"ns=2;s=模拟器示例.01分站状态.01状态{num:04d}" for num in range(1, total + 1)]

        # 基础请求数据
        base_login_data = {
            "DioModel": {
                "SystemID": 2177086216363009,
                "PointCode": None,
                "PointGroupID": 1,
                "PointTypeID": 4868641757800449,
                "PointValueType": 2,
                "Priority": 0,
                "PointWritable": 0,
                "PointValueDecimalDigits": 2,
                "ValueShowString": "开,关",
                "BelongChannelID": 2179167501980673,
                "DataAcquisitionTypes": 1,
                "AcquisitionFrequency": 1000,
                "DataStorageType": 2,
                "Interval": 1,
                "Remark": None,
                "FeedbackPointIDs": None,
                "AffectAreas": None,
                "AreaID": 0,
                "PositionID": 0,
                "IsReverse": 0
            },
            "AlarmModel": {
                "AlarmType": 1,
                "IsZeroStateAlarm": 0,
                "IsOneStateAlarm": 1,
                "Parmas": "[{\"Pname\":\"AlarmRuleType\",\"Pvalue\":0}]"
            },
            "PreAlarmModel": {
                "PreAlarmType": 1,
                "IsUseMultiPreAlarm": 0,
                "BelongPreAlarmGroupID": 0,
                "IsZeroStatePreAlarm": 0,
                "IsOneStatePreAlarm": 0
            },
            "ControlModels": [],
            "AlarmVoiceModel": {
                "Content": "${item.PointName}发生了${item.AlarmTypeName}，监测值为${item.CurrentValue}",
                "IsEnable": 0,
                "PlayCount": 1
            },
            "MultiStateAlarmConfigs": None,
            "MultiStatePreAlarmConfigs": None
        }

        # 并发创建测点
        with ThreadPoolExecutor(max_workers=10) as executor:
            futures = []

            for i in range(start, start + total):
                if not self.running:
                    self.logger.info("用户终止了测点创建操作")
                    break

                idx = i - start
                data_source = data_sources[idx] if idx < len(data_sources) else f"ns=2;s=自定义状态{idx:04d}"

                # 构建请求数据
                formatted_str = str(i).zfill(5)
                full_number = f"№_{formatted_str}工作面_分站_状态"

                dynamic_data = {
                    "DioModel": {
                        "PointName": full_number,
                        "DataSource": data_source
                    }
                }

                login_data = copy.deepcopy(base_login_data)
                login_data["DioModel"].update(dynamic_data["DioModel"])

                # 提交任务
                future = executor.submit(
                    self._create_single_point,
                    i,
                    server_ip,
                    authorization,
                    login_data
                )
                futures.append(future)

                # 每10个点更新一次进度
                if (i - start + 1) % 10 == 0:
                    progress = (i - start + 1) / total * 100
                    progress_callback(progress, success_count, error_count)

            # 处理结果
            for future in futures:
                if not self.running:
                    break

                success, result = future.result()
                if success:
                    success_count += 1
                    point_id = result
                    if point_id % 100 == 0:
                        self.logger.info(f"成功创建测点 {point_id}")
                else:
                    error_count += 1
                    error_info = result
                    self.logger.error(
                        f"创建测点失败 - 编号: {error_info['point_id']}, 错误: {error_info['error_message']}")

                # 每10个点更新一次进度
                if (success_count + error_count) % 10 == 0:
                    progress = (success_count + error_count) / total * 100
                    progress_callback(progress, success_count, error_count)

        # 最终更新
        progress_callback(100, success_count, error_count)
        self.logger.info(f"测点创建完成 - 成功: {success_count}, 失败: {error_count}")
        status_callback(True, {
            "total": total,
            "success": success_count,
            "error": error_count
        })

    def _create_single_point(self, point_id, server_ip, authorization, data):
        """创建单个测点"""
        url = f"http://{server_ip}:4200/v1/common/SaveDioPointAssemble"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {authorization}"
        }

        try:
            success, response = self.http_client.post(url, headers=headers, data=data)

            if success and response.get('status_code') == 201:
                return True, point_id
            else:
                error_msg = response.get('error_message', f"创建测点 {point_id} 失败")
                status_code = response.get('status_code', '未知')
                return False, {
                    "point_id": point_id,
                    "error_message": error_msg,
                    "status_code": status_code
                }

        except Exception as e:
            return False, {
                "point_id": point_id,
                "error_message": f"创建测点时发生异常: {str(e)}",
                "error_type": type(e).__name__
            }

    def stop_creation(self):
        """停止创建任务"""
        self.running = False
        self.logger.info("接收到停止创建测点的请求")